From 53e07a51b1d222a05dce9dc1aad0fdda03076677 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Mon, 14 Jul 2003 21:27:17 +0000 Subject: [PATCH] bitkeeper revision 1.339.1.11 (3f132035CGTz70qQug_kGM8wm0k5gw) dev.c, xen_block.c, kernel.c, setup.c, nmi.c: Fixed deadlock race in network code. Watchdog timer is now disabled by default. Improved tracing in Xen blkdev code. --- xen/arch/i386/nmi.c | 11 +++++++---- xen/arch/i386/setup.c | 9 ++++++--- xen/common/kernel.c | 3 ++- xen/drivers/block/xen_block.c | 8 ++++---- xen/net/dev.c | 13 +++++++++++-- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/xen/arch/i386/nmi.c b/xen/arch/i386/nmi.c index 23fd691fe1..f48efb2322 100644 --- a/xen/arch/i386/nmi.c +++ b/xen/arch/i386/nmi.c @@ -27,10 +27,7 @@ #include #include -#undef Dprintk -#define Dprintk(x...) printk(x) - -unsigned int nmi_watchdog = NMI_LOCAL_APIC; +unsigned int nmi_watchdog = NMI_NONE; static unsigned int nmi_hz = HZ; unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ extern void show_registers(struct pt_regs *regs); @@ -80,6 +77,9 @@ int __init check_nmi_watchdog (void) unsigned int prev_nmi_count[NR_CPUS]; int j, cpu; + if (!nmi_watchdog) + return 0; + printk("testing NMI watchdog ---\n"); for (j = 0; j < smp_num_cpus; j++) { @@ -197,6 +197,9 @@ static int __pminit setup_p4_watchdog(void) void __pminit setup_apic_nmi_watchdog (void) { + if (!nmi_watchdog) + return; + switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15) diff --git a/xen/arch/i386/setup.c b/xen/arch/i386/setup.c index 1372c7b403..1e3695f847 100644 --- a/xen/arch/i386/setup.c +++ b/xen/arch/i386/setup.c @@ -286,17 +286,20 @@ void __init start_of_day(void) extern void tqueue_bh(void); extern void immediate_bh(void); extern void init_timervecs(void); - extern void disable_pit(void); - extern void ac_timer_init(void); + extern void disable_pit(void); + extern void ac_timer_init(void); extern int setup_network_devices(void); extern void net_init(void); extern void initialize_block_io(void); extern void initialize_keytable(); extern void initialize_serial(void); extern void initialize_keyboard(void); - extern int opt_nosmp; + extern int opt_nosmp, opt_watchdog; unsigned long low_mem_size; + if ( opt_watchdog ) + nmi_watchdog = NMI_LOCAL_APIC; + /* * We do this early, but tables are in the lowest 1MB (usually * 0xfe000-0xfffff). Therefore they're unlikely to ever get clobbered. diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 999c88fd4b..896dd8e735 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -41,7 +41,7 @@ unsigned int opt_ser_baud = 9600; /* default baud for COM1 */ unsigned int opt_dom0_mem = 16000; /* default kbytes for DOM0 */ unsigned int opt_ne_base = 0; /* NE2k NICs cannot be probed */ unsigned char opt_ifname[10] = "eth0"; -int opt_noht=0, opt_noacpi=0, opt_nosmp=0; +int opt_noht=0, opt_noacpi=0, opt_nosmp=0, opt_watchdog=0; enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL }; static struct { unsigned char *name; @@ -56,6 +56,7 @@ static struct { { "noht", OPT_BOOL, &opt_noht }, { "noacpi", OPT_BOOL, &opt_noacpi }, { "nosmp", OPT_BOOL, &opt_nosmp }, + { "watchdog", OPT_BOOL, &opt_watchdog }, { NULL, 0, NULL } }; diff --git a/xen/drivers/block/xen_block.c b/xen/drivers/block/xen_block.c index 644f91254d..369cbfe463 100644 --- a/xen/drivers/block/xen_block.c +++ b/xen/drivers/block/xen_block.c @@ -704,14 +704,14 @@ static void dispatch_rw_block_io(struct task_struct *p, int index) phys_seg[nr_psegs].nr_sects = nr_sects; if (p->domain != 0 && !xen_physdisk_access_okay(&phys_seg[nr_psegs], p, operation)) { - DPRINTK("access denied\n"); - /* XXX not quite right, but close enough. */ - goto bad_descriptor; + DPRINTK("access denied: dev=%04x off=%ld nr=%ld\n", + req->device, req->sector_number + tot_sects, nr_sects); + goto bad_descriptor; } phys_seg[nr_psegs].dev = xendev_to_physdev(req->device); if ( phys_seg[nr_psegs].dev == 0 ) { - DPRINTK("bad device\n"); + DPRINTK("bad device: %04x\n", req_device); goto bad_descriptor; } new_segs = 1; diff --git a/xen/net/dev.c b/xen/net/dev.c index 471b0ae5c5..f1ce37cf92 100644 --- a/xen/net/dev.c +++ b/xen/net/dev.c @@ -1768,7 +1768,7 @@ long do_net_update(void) net_vif_t *vif; net_idx_t *shared_idxs; unsigned int i, j, idx; - struct sk_buff *skb; + struct sk_buff *skb, *interdom_skb = NULL; tx_req_entry_t tx; rx_req_entry_t rx; unsigned long pte_pfn, buf_pfn; @@ -1889,7 +1889,11 @@ long do_net_update(void) skb->len = tx.size - ETH_HLEN; unmap_domain_mem(skb->head); - (void)netif_rx(skb); + /* + * We must defer netif_rx until we have released the current + * domain's page_lock, or we may deadlock on SMP. + */ + interdom_skb = skb; make_tx_response(vif, tx.id, RING_STATUS_OK); } @@ -1897,6 +1901,11 @@ long do_net_update(void) tx_unmap_and_continue: unmap_domain_mem(g_data); spin_unlock_irq(¤t->page_lock); + if ( interdom_skb != NULL ) + { + (void)netif_rx(interdom_skb); + interdom_skb = NULL; + } } vif->tx_req_cons = i; -- 2.30.2